﻿using System;
using Glue.Internals.Nulls;

namespace Glue.Internals
{
    internal partial class ObjectMemberFactory
    {
        private class ObjectMember : IObjectMember
        {
            private readonly IObjectMemberAccessor memberAccessor;

            public String Name { get; private set; }
            public bool CanGetValues { get; private set; }
            public bool CanSetValues { get; private set; }

            public Type MemberType { get; private set; }

            internal ObjectMember(IObjectMemberAccessor memberAccessor, bool canSetValues)
            {
                this.memberAccessor = memberAccessor;
                Name = memberAccessor.Name;
                CanGetValues = memberAccessor.CanGetValues;
                CanSetValues = canSetValues;
                MemberType = memberAccessor.PropertyType;
            }

            internal ObjectMember(IObjectMemberAccessor memberAccessor):this(memberAccessor,memberAccessor.CanSetValues) {}

            public virtual object InvokeGet(object toInvokeOn)
            {
                var maybe = memberAccessor.InvokeGet(toInvokeOn);
                return maybe.HasValue()?maybe.GetValue():null;
            }

            public virtual void InvokeSet(object toInvokeOn, object toSet)
            {
                memberAccessor.InvokeSet(toInvokeOn, toSet);
            }

            public Maybe<IHoldDifferentBaseMemberName> GetParentProperty()
            {
                return (memberAccessor as IHoldDifferentBaseMemberName).AsMaybe();
            }

            public bool CanMapFrom(object thisObject)
            {
                return memberAccessor.CanMapFrom(thisObject);
            }
        }
    }
}